/**
 * 认证管理工具
 * 使用localStorage实现Token持久化，支持记住我功能
 * 完全替代cookie方案，提升安全性和性能
 */

import { User } from "../contexts/UserContext";

interface TokenOptions {
  remember?: boolean;
  expiresIn?: number; // 过期时间（秒）
}

export class AuthService {
  private static readonly TOKEN_KEY = "authToken";
  private static readonly USER_KEY = "authUser";
  private static readonly REMEMBER_KEY = "rememberMe";
  private static readonly EXPIRES_KEY = "authTokenExpires";

  /**
   * 保存Token到本地存储
   * @param token JWT Token
   * @param user 用户信息
   * @param options 存储选项
   */
  static setToken(
    token: string,
    user?: User,
    options: TokenOptions = {}
  ): void {
    const { remember = true, expiresIn } = options;

    if (remember) {
      // 使用localStorage长期保存
      localStorage.setItem(this.TOKEN_KEY, token);
      localStorage.setItem(this.REMEMBER_KEY, "true");

      if (user) {
        localStorage.setItem(this.USER_KEY, JSON.stringify(user));
      }

      // 如果有过期时间，保存过期时间戳
      if (expiresIn) {
        const expiresAt = Date.now() + expiresIn * 1000;
        localStorage.setItem(this.EXPIRES_KEY, expiresAt.toString());
      }
    } else {
      // 使用sessionStorage会话保存
      sessionStorage.setItem(this.TOKEN_KEY, token);
      localStorage.setItem(this.REMEMBER_KEY, "false");

      if (user) {
        sessionStorage.setItem(this.USER_KEY, JSON.stringify(user));
      }

      if (expiresIn) {
        const expiresAt = Date.now() + expiresIn * 1000;
        sessionStorage.setItem(this.EXPIRES_KEY, expiresAt.toString());
      }
    }
  }

  /**
   * 获取Token
   */
  static getToken(): string | null {
    // 首先检查localStorage
    let token = localStorage.getItem(this.TOKEN_KEY);

    // 如果localStorage没有，检查sessionStorage
    if (!token) {
      token = sessionStorage.getItem(this.TOKEN_KEY);
    }

    // 检查Token是否过期
    if (token && this.isTokenExpired()) {
      this.removeToken();
      return null;
    }

    return token;
  }

  /**
   * 获取用户信息
   */
  static getUser(): User | null {
    try {
      let userStr = localStorage.getItem(this.USER_KEY);
      if (!userStr) {
        userStr = sessionStorage.getItem(this.USER_KEY);
      }

      return userStr ? JSON.parse(userStr) : null;
    } catch (error) {
      console.error("解析用户信息失败:", error);
      return null;
    }
  }

  /**
   * 检查Token是否过期
   */
  static isTokenExpired(): boolean {
    let expiresAt = localStorage.getItem(this.EXPIRES_KEY);
    if (!expiresAt) {
      expiresAt = sessionStorage.getItem(this.EXPIRES_KEY);
    }

    if (!expiresAt) {
      // 如果没有过期时间，认为token有效
      console.log("ℹ️ 未找到过期时间，假设token有效");
      return false;
    }

    const expireTime = parseInt(expiresAt);
    const currentTime = Date.now();

    // 增加5分钟的容错时间，避免因为时间差异导致的意外退出
    const gracePeriod = 5 * 60 * 1000; // 5分钟
    const isExpired = currentTime > expireTime + gracePeriod;

    if (isExpired) {
      console.log("⏰ Token已过期:", {
        expireTime: new Date(expireTime).toLocaleString(),
        currentTime: new Date(currentTime).toLocaleString(),
        expired: isExpired,
      });
    }

    return isExpired;
  }

  /**
   * 检查是否已认证
   */
  static isAuthenticated(): boolean {
    const token = this.getToken();
    const isExpired = this.isTokenExpired();
    const isAuth = !!token && !isExpired;

    console.log("🔍 认证状态检查:", {
      hasToken: !!token,
      isExpired: isExpired,
      isAuthenticated: isAuth,
    });

    return isAuth;
  }

  /**
   * 获取记住我设置
   */
  static getRememberMe(): boolean {
    return localStorage.getItem(this.REMEMBER_KEY) === "true";
  }

  /**
   * 清除Token和用户信息
   */
  static removeToken(): void {
    // 清除localStorage
    localStorage.removeItem(this.TOKEN_KEY);
    localStorage.removeItem(this.USER_KEY);
    localStorage.removeItem(this.EXPIRES_KEY);
    localStorage.removeItem(this.REMEMBER_KEY);

    // 清除sessionStorage
    sessionStorage.removeItem(this.TOKEN_KEY);
    sessionStorage.removeItem(this.USER_KEY);
    sessionStorage.removeItem(this.EXPIRES_KEY);

    // 清理所有相关的本地存储
    Object.keys(localStorage).forEach((key) => {
      if (
        key.startsWith("app_") ||
        key.startsWith("cache_") ||
        key.startsWith("auth_")
      ) {
        localStorage.removeItem(key);
      }
    });
  }

  /**
   * 清理所有cookie（用于从cookie迁移到localStorage）
   */
  static clearAllCookies(): void {
    const cookies = ["token", "user", "authToken", "authUser"];
    cookies.forEach((name) => {
      // 删除根路径的cookie
      document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/;`;
      // 删除当前路径的cookie
      document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=${window.location.pathname};`;
      // 删除域名级别的cookie
      document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/;domain=${window.location.hostname};`;
    });
  }

  /**
   * 从cookie迁移到localStorage
   */
  static migrateCookieToLocalStorage(): void {
    // 检查是否有cookie中的token
    const cookieToken = this.getCookie("token");
    const cookieUser = this.getCookie("user");

    if (cookieToken && !this.getToken()) {
      console.log("正在从Cookie迁移到localStorage...");

      let user = null;
      if (cookieUser) {
        try {
          user = JSON.parse(cookieUser);
        } catch (error) {
          console.error("解析Cookie用户信息失败:", error);
        }
      }

      // 设置到localStorage（默认记住我）
      this.setToken(cookieToken, user, { remember: true });

      // 清理cookie
      this.clearAllCookies();

      console.log("Cookie迁移完成");
    }
  }

  /**
   * 获取Cookie值（用于迁移）
   */
  private static getCookie(name: string): string | null {
    const nameEQ = name + "=";
    const ca = document.cookie.split(";");
    for (let i = 0; i < ca.length; i++) {
      let c = ca[i];
      while (c.charAt(0) === " ") c = c.substring(1, c.length);
      if (c.indexOf(nameEQ) === 0) {
        return decodeURIComponent(c.substring(nameEQ.length, c.length));
      }
    }
    return null;
  }

  /**
   * 刷新Token
   */
  static async refreshToken(): Promise<string | null> {
    try {
      const response = await fetch("/api/v1/auth/refresh", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${this.getToken()}`,
        },
      });

      if (response.ok) {
        const data = await response.json();
        if (data.code === 0 && data.data.token) {
          const user = this.getUser();
          const remember = this.getRememberMe();
          this.setToken(data.data.token, user || undefined, { remember });
          return data.data.token;
        }
      }
    } catch (error) {
      console.error("Token刷新失败:", error);
    }

    return null;
  }

  /**
   * 初始化认证状态（应用启动时调用）
   */
  static initialize(): void {
    // 执行cookie迁移
    this.migrateCookieToLocalStorage();

    // 清理过期的存储项
    this.cleanupExpiredStorage();
  }

  /**
   * 清理过期的存储项
   */
  private static cleanupExpiredStorage(): void {
    if (this.isTokenExpired()) {
      console.log("Token已过期，清理认证信息");
      this.removeToken();
    }
  }

  /**
   * 获取认证状态信息（用于调试）
   */
  static getAuthInfo() {
    return {
      hasToken: !!this.getToken(),
      isAuthenticated: this.isAuthenticated(),
      rememberMe: this.getRememberMe(),
      user: this.getUser(),
      tokenExpired: this.isTokenExpired(),
    };
  }
}
